package com.linjiahao.userCenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linjiahao.servicebase.common.BaseConstant;
import com.linjiahao.servicebase.common.NettyMessageType;
import com.linjiahao.servicebase.common.RedisService;
import com.linjiahao.servicebase.common.ResultMap;
import com.linjiahao.servicebase.exception.ErrorMessage;
import com.linjiahao.servicebase.exception.WebChatException;
import com.linjiahao.servicebase.vo.NettyMessageVO;
import com.linjiahao.userCenter.client.NettyServerClient;
import com.linjiahao.userCenter.domain.ChatFriend;
import com.linjiahao.userCenter.mapper.ChatUserInfoMapper;
import com.linjiahao.userCenter.service.ChatFriendService;
import com.linjiahao.userCenter.mapper.ChatFriendMapper;
import com.linjiahao.userCenter.util.PinYinUtil;
import com.linjiahao.userCenter.vo.AddFriendVO;
import com.linjiahao.userCenter.vo.AddOrRejectVO;
import com.linjiahao.userCenter.vo.PersonInfoVO;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * @ClassName ChatUserInfoServiceImpl
 * @Description: 用户好友抽象实现类
 * @Author linjiahao
 * @Date 6/1/2021
 **/
@Service
public class ChatFriendServiceImpl extends ServiceImpl<ChatFriendMapper, ChatFriend> implements ChatFriendService{

    @Resource
    private NettyServerClient nettyServerClient;

    @Resource
    private ChatUserInfoMapper chatUserInfoMapper;

    @Resource(name = "MessageTaskExecutor")
    private Executor messageTaskExecutor;


    @Override
    public ResultMap applyFriend(AddFriendVO addFriendVO,Long userId) {
        if(addFriendVO.getFriendId().equals(userId)){
            throw new WebChatException(ErrorMessage.NOT_ALLOW_ADD_MYSELF.getErrorCode(),ErrorMessage.NOT_ALLOW_ADD_MYSELF.getMessage());
        }
        //查找是否已经存在申请记录
        LambdaQueryWrapper<ChatFriend> wrapper = new LambdaQueryWrapper<ChatFriend>().eq(ChatFriend::getUserId, userId).eq(ChatFriend::getFriendId, addFriendVO.getFriendId())
                .eq(ChatFriend::getIsPass, BaseConstant.Not_Pass).eq(ChatFriend::getIsDelete,BaseConstant.Not_Pass);
        ChatFriend oldOne = this.baseMapper.selectOne(wrapper);
        int count = 0;
        if(oldOne==null){
            ChatFriend chatFriend = new ChatFriend().initChatFriend(userId,
                    addFriendVO.getFriendId(), addFriendVO.getApplyReason(),BaseConstant.Not_Pass);
            //业务保存申请
            count = this.baseMapper.insert(chatFriend);
        }else {
            ChatFriend chatFriend = new ChatFriend();
            chatFriend.setApplyReason(addFriendVO.getApplyReason());
            LambdaUpdateWrapper<ChatFriend> updateWrapper = new UpdateWrapper<ChatFriend>().lambda().eq(ChatFriend::getBizId,oldOne.getBizId());
            count = this.baseMapper.update(chatFriend, updateWrapper);
        }
        //通过netty 实时发送申请消息
        NettyMessageVO nettyMessageVO = new NettyMessageVO();
        nettyMessageVO.setUserId(userId);
        nettyMessageVO.setReceiveId(addFriendVO.getFriendId());
        nettyMessageVO.setData(addFriendVO.getApplyReason());
        nettyMessageVO.setMessageType(NettyMessageType.ADD_FRIEND.getType());
        messageTaskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                nettyServerClient.sendMessageApi(nettyMessageVO);
            }
        });
        return count>0?ResultMap.ok():ResultMap.error();
    }

    @Override
    public ResultMap getFriendList(Long userId) throws BadHanyuPinyinOutputFormatCombination {
        LambdaQueryWrapper<ChatFriend> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatFriend::getUserId,userId).eq(ChatFriend::getIsPass,BaseConstant.Pass)
                .eq(ChatFriend::getIsDelete,BaseConstant.Not_Pass).select(ChatFriend::getFriendId,ChatFriend::getRemark);
        List<ChatFriend> friendList = this.baseMapper.selectList(wrapper);
        List<PersonInfoVO> list = new ArrayList<>();
        if(!CollectionUtils.isEmpty(friendList)){
            Map<Long, String> map = friendList.stream().collect(Collectors.toMap(ChatFriend::getFriendId, ChatFriend::getRemark, (k1, k2) -> k1));
            //把自己也加上
            List<Long> userIds = new ArrayList<>(map.keySet());
            userIds.add(userId);
            list = chatUserInfoMapper.getFriendInfoList(userIds);
            //根据nickName 的首写字母分组排序
            list = PinYinUtil.getUserCodeGroup(list);
            //设置备注
            list.stream().forEach(m ->{
                m.setRemark(map.get(m.getUserId()));
            });
        }else {
            List<Long> userIds = new ArrayList<>();
            userIds.add(userId);
            list = chatUserInfoMapper.getFriendInfoList(userIds);
            //根据nickName 的首写字母分组排序
            list = PinYinUtil.getUserCodeGroup(list);
        }

        return ResultMap.ok().data("friendList",list);
    }

    @Override
    public ResultMap getApplyFriendList(Long userId) {
        LambdaQueryWrapper<ChatFriend> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatFriend::getFriendId,userId).eq(ChatFriend::getIsPass,BaseConstant.Not_Pass)
                .eq(ChatFriend::getIsDelete,BaseConstant.Not_Pass).select(ChatFriend::getUserId,ChatFriend::getApplyReason,ChatFriend::getBizId);
        List<ChatFriend> applyFriendList = this.baseMapper.selectList(wrapper);
        List<PersonInfoVO> list = new ArrayList<>();
        if(!CollectionUtils.isEmpty(applyFriendList)){
            Map<Long, ChatFriend> map = applyFriendList.stream().collect(Collectors.toMap(ChatFriend::getUserId, a->a, (k1, k2) -> k1));
            List<Long> userIds = new ArrayList<>(map.keySet());
            list = chatUserInfoMapper.getFriendInfoList(userIds);
            //设置申请原因
            list.stream().forEach(m ->{
                m.setApplyReason(map.get(m.getUserId()).getApplyReason());
                m.setBizId(map.get(m.getUserId()).getBizId());
            });
        }
        return ResultMap.ok().data("applyFriendList",list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultMap addOrRejectFriend(AddOrRejectVO addOrRejectVO, Long userId) {
        //查询是否有该申请记录
        ChatFriend chatFriend = this.baseMapper.selectOne(new QueryWrapper<ChatFriend>().lambda().eq(ChatFriend::getBizId, addOrRejectVO.getBizId()));
        if(chatFriend == null){
            throw new WebChatException(ErrorMessage.ADD_FRIEND_FAIL.getErrorCode(),ErrorMessage.ADD_FRIEND_FAIL.getMessage());
        }
        int count = 0;
        ChatFriend updateFriend = new ChatFriend();
        if(addOrRejectVO.getFlag()){
            updateFriend.setIsPass(BaseConstant.Pass);
            //添加新的一条接受人的通过记录
            ChatFriend friend = new ChatFriend().initChatFriend(userId, chatFriend.getUserId(), "", BaseConstant.Pass);
            count = this.baseMapper.insert(friend);
            //给申请人发送消息
            NettyMessageVO nettyMessageVO = new NettyMessageVO();
            nettyMessageVO.setUserId(userId);
            nettyMessageVO.setReceiveId(chatFriend.getUserId());
            nettyMessageVO.setData("");
            nettyMessageVO.setMessageType(NettyMessageType.ADD_FRIEND_FISH.getType());
            messageTaskExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    nettyServerClient.sendMessageApi(nettyMessageVO);
                }
            });
        }else {
            updateFriend.setIsDelete(BaseConstant.Pass);
        }
        UpdateWrapper<ChatFriend> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(ChatFriend::getBizId,addOrRejectVO.getBizId());
        //更新申请人的状态
        this.baseMapper.update(updateFriend,wrapper);
        return  count>0?ResultMap.ok():ResultMap.error();
    }

    @Override
    public ResultMap searchMyFriend(String keyWord, Long userId) throws BadHanyuPinyinOutputFormatCombination {
        //当前搜索不包括自己
        List<PersonInfoVO> list = this.baseMapper.searchMyFriend(keyWord,userId);
        if(!CollectionUtils.isEmpty(list)){
            list = PinYinUtil.getUserCodeGroup(list);
        }
        return ResultMap.ok().data("searchList",list);
    }
}
